import java.io.File;
import java.io.IOException;
import java.util.logging.*;


public class Lab1FileSet implements FileSet {

	private final int numFiles = 4;
	private final int lineLength = 80;
	private FileProcessor processor; 
	private File primIn, auxIn, resultOut, reportOut;
	private Logger LOG;
	private LogSetup logSet;

	public Lab1FileSet (String[] fileNames) throws IllegalArgumentException{
		logSet = new LogSetup(LOG);
		LOG = logSet.initializeToErr("BasicMFP");//set up an error log that goes to System.err
		if (fileNames.length != numFiles){
			LOG.severe("001: Invalid number of arguments; Expected "+  numFiles + " receieved "+ fileNames.length +" ");
			throw new IllegalArgumentException();//throw an exception if the wrong number of args are entered
		}		
		primIn = new File(fileNames[0]);
		auxIn = new File(fileNames[1]);
		resultOut = new File(fileNames[2]);
		reportOut = new File(fileNames[3]);
		processor = new BasicFileProcessor(LOG);
	}

	/* (non-Javadoc)
	 * @see FileSet#checkFiles()
	 */
	@Override
	public boolean checkFiles() {
		boolean result;
		result = writeableOutput(reportOut);//make sure report is valid
		if (result){
				result = logSet.setInfoLog(reportOut);
		}
		result &= writeableOutput (resultOut);//check other files for validity
		result &= readableInput (primIn);
		result &= readableInput (auxIn);
		return result;
	}

	private boolean readableInput(File in) {//check that input files exist and are readable
		boolean canRead = false;
		boolean isDirectory = true;
		try{
			canRead = in.canRead();//checks for existence and readability
		} 
		catch(SecurityException e){//only throws exception if not readable, which is fine
		}
		isDirectory = in.isDirectory();

		if (! canRead){
			LOG.severe("002: "+ in.getName() + " does not exist or is not readable." );//if we can't use it log an error
		}
		if (isDirectory){
			LOG.severe("003: "+ in.getName()+ " is a directory.");//if we can't use it log an error
		}
		return canRead && ! isDirectory;
	}

	private boolean writeableOutput(File out) {// check that output files don't exist and are in writeable directories
		File parent = out.getParentFile();//temp variable to get info on parent directory
		if (parent == null){
			parent = new File (".");
		}
		boolean thisExists = false;
		boolean parentWriteable = false;
		try{
			thisExists = out.exists();
			parentWriteable = new File(".").canWrite();
		}
		catch (SecurityException e){//only throws exception if parent isn't writeable, which is fine
		}
		if (thisExists){
			LOG.severe("004: " + out.getName() + " already exists.");//record error if output file already exists
		}
		if (! parentWriteable){
			LOG.severe("005: " + out.getName() + " is in a directory which is not writeable");//record error if parent directory isn't writeable
		}
		return (! thisExists) && parentWriteable;
	}


	/* (non-Javadoc)
	 * @see FileSet#processFiles()
	 */
	@Override
	public void processFiles() {
		try {
			int numLines = processor.processAuxFile(auxIn);
			if (numLines>0){
				processor.processPrimaryFile(primIn, resultOut, numLines, lineLength);
			}
		}
		catch (IOException e) {
			LOG.severe("???: IO Error");//TODO
		}
	}
}
